package net.expectx.micro.shop.api.manager.impl;


import net.expectx.micro.shop.api.authorization.exception.MethodNotSupportException;
import net.expectx.micro.shop.api.manager.TokenManager;

/**
 * Token管理的基础类
 * @author jianhun_ygl
 * @date 2017-11-03
 */
public abstract class AbstractTokenManager implements TokenManager {

    protected int tokenExpireSeconds = 7 * 24 * 3600;

    protected boolean singleTokenWithUser = true;

    protected boolean flushExpireAfterOperation = true;

    public void setTokenExpireSeconds(int tokenExpireSeconds) {

        this.tokenExpireSeconds = tokenExpireSeconds;

    }

    public void setSingleTokenWithUser(boolean signleTokenWithUser) {

        this.singleTokenWithUser = signleTokenWithUser;

    }

    public void setFlushExpireAfterOperation(boolean flushExpireAfterOperation) {

        this.flushExpireAfterOperation = flushExpireAfterOperation;

    }

    @Override
    public void createRelationship(String key, String token) {

        //根据设置的每个用户是否只允许绑定一个Token，调用不同的方法
        if(singleTokenWithUser) {
            createSingleRelationship(key, token);
        } else {
            createMultipleRelationship(key, token);
        }

    }

    /**
     * 一个用户只能绑定一个Token时创建关联关系
     * @param key
     * @param token
     */
    protected abstract void  createSingleRelationship(String key, String token);

    /**
     * 一个用户可以绑定多个Token时创建关联关系
     * @param key
     * @param token
     */
    protected abstract void createMultipleRelationship(String key, String token);

    @Override
    public void delRelationshipByKey(String key) {

        if(!singleTokenWithUser) {
            throw new MethodNotSupportException("非单点登录时无法调用该方法");
        }
        delSingleRelationshipByKey(key);

    }

    /**
     * 一个用户只能绑定一个Token时删除关联关系
     * @param key
     */
    protected abstract void delSingleRelationshipByKey(String key);


    @Override
    public String getKey(String token) {

        String key = getKeyByToken(token);
        if(key != null && flushExpireAfterOperation) {
            flushExpireAfterOperation(key, token);
        }
        return key;

    }

    /**
     * 通过Token获得Key
     * @param token
     * @return
     */
    protected abstract String getKeyByToken(String token);

    /**
     * 在操作后刷新Token的过期时间
     * @param key
     * @param token
     */
    protected abstract void flushExpireAfterOperation(String key, String token);

}
